package com.example.service;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.example.constants.consts.SendSms;
import com.example.utils.PhoneUtil;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import lombok.extern.slf4j.Slf4j;

/**
 * 类SendSmsService.java的实现描述：TODO 发送通知短信
 * 
 * @author 李隆铨 2019年1月22日 下午3:33:10
 */
@Slf4j
@Service(value = "sendSmsService")
public class SendSmsService {

    /** 中国区号 */
    private static final Integer AREA_CODE = 86;
    /** http请求返回状态码 */
    private static final Integer OK        = 200;

    /**
     * 发送短信
     * 
     * @param phone
     * @return
     * @throws Exception
     */
    public static boolean sendSms(String phone) throws Exception {
        boolean isSuccess = false;
        if (!PhoneUtil.checkPhoneNumber(phone, AREA_CODE)) {
            log.error("手机号码有误,请确认！");
            throw new Exception("手机号码有误!!");
        }
        String rod = smsCode();
        String timestamp = getTimestamp();
        String sig = encryption(SendSms.ACCOUNT_SID, SendSms.AUTH_TOKEN, timestamp);
        String tamp = "【蜗牛通讯】您的验证码为" + rod + "，请于" + 5 + "分钟内正确输入，如非本人操作，请忽略此短信。";
        Map<String, Object> parameter = new HashMap<>();
        parameter.put("accountSid", SendSms.ACCOUNT_SID);
        parameter.put("smsContent", tamp);
        parameter.put("to", phone);
        parameter.put("timestamp", timestamp);
        parameter.put("sig", sig);
        parameter.put("respDataType", SendSms.DEFAULT_RESPDATATYPE);
        HttpResponse response = null;
        try {
            response = HttpRequest.post(SendSms.SEND_SMS_URL)
                    .header("Content-type", "application/x-www-form-urlencoded").form(parameter).timeout(6000)
                    .execute();
            if (response != null && response.getStatus() == OK) {
                JSONObject jsonObject = JSONObject.parseObject(response.body());
                log.info("respCode为{}", jsonObject.getString("respCode"));
                if (StrUtil.equals(SendSms.RESPCODE, jsonObject.getString(SendSms.STATUS_FIELD))) {
                    isSuccess = true;
                    log.info("手机号码:{},短信发送成功,时间：{}", phone, getTimestamp());
                }
            }
        } catch (Exception e) {
            log.error("http请求出错,响应状态码为{}", response.getStatus());
        }
        return isSuccess;

    }

    /**
     * sing签名
     * 
     * @param sid
     * @param token
     * @param timestamp
     * @return
     */
    private static String encryption(String sid, String token, String timestamp) {

        StringBuilder result = new StringBuilder();
        String source = sid + token + timestamp;
        // 获取某个类的实例
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            // 要进行加密的东西
            byte[] bytes = digest.digest(source.getBytes());
            for (byte b : bytes) {
                String hex = Integer.toHexString(b & 0xff);
                if (hex.length() == 1) {
                    result.append("0" + hex);
                } else {
                    result.append(hex);
                }
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        return result.toString();
    }

    /**
     * 线程安全获取时间戳
     * 
     * @return
     */
    private static String getTimestamp() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
    }

    /**
     * 创建验证码 获得6位随机数
     * 
     * @return
     */
    private static String smsCode() {
        //(Math.random() * 9 + 1) * 100000  Math.random()生成大于等于0并小于1的数字
        return String.valueOf(RandomUtil.randomInt(100000, 999999));
    }

    public static void main(String[] args) throws Exception {
        System.out.println(getTimestamp());
        System.out.println(sendSms("17621715160"));
        log.info(StrUtil.toString(sendSms("17621715160")));

    }

}
